// ============================ lwip_http_api.h ============================
// A tiny GET/POST routing layer on top of lwIP httpd (raw API, NO_SYS friendly)
// 轻量 GET/POST 路由层（零 malloc / 纯 C），在不改变旧接口的基础上，增加“语法糖”封装。
// ---------------------------------------------------------------------------
#pragma once
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

// ================= 原有公共 API（保持不变，向后兼容） =================
typedef enum { HM_GET = 0, HM_POST = 1 } http_method_t;

// 只读 KV 视图
typedef struct { const char* key; const char* val; } http_kv_t;

// 请求对象（保持字段不变）
typedef struct {
  http_method_t  method;           // GET / POST
  const char*    uri;              // 路径（不含 query），如 "/api/sum"
  int            qcount;           // query[] 中项数
  http_kv_t      query[16];        // 来自 GET ?a=1&b=2 或 POST form
  const char*    body;             // POST 原始 body（可为 JSON）
  int            body_len;         // body 长度
  const char*    content_type;     // 来自请求头（若可解析）
} http_req_t;

// 响应对象（保持字段不变）
typedef struct {
  int            status;           // 默认 200
  const char*    content_type;     // 默认 "application/json"
  char*          out;              // 输出缓冲（由底座提供）
  int            cap;              // 缓冲容量
  int            len;              // 已写入长度
} http_res_t;

// 处理函数（保持不变）
typedef int (*route_fn)(const http_req_t* req, http_res_t* res);

// ---- 路由注册（保持不变） ----
void HTTP_API_register(http_method_t m, const char* path, route_fn fn);
#define HTTP_API_ROUTE_GET(path, fn)   HTTP_API_register(HM_GET,  (path), (fn))
#define HTTP_API_ROUTE_POST(path, fn)  HTTP_API_register(HM_POST, (path), (fn))

// ---- 初始化（保持不变） ----
// 在 httpd_init() 之后调用，用于建立 CGI 表和启用自定义 FS 钩子
void HTTP_API_init(void);

// 由用户实现，在此函数中注册路由；底座 .c 会用 weak 符号调用
void HTTP_API_user_routes(void);

// ---- 小工具（保持不变） ----
const char* http_kv_get(const http_req_t* r, const char* k);
int         http_kv_get_int(const http_req_t* r, const char* k, int defv);
void        http_res_set_status(http_res_t* r, int s);
void        http_res_set_type  (http_res_t* r, const char* t);

// ========================================================================
// ========================== “加糖”便捷扩展 ==============================
// ========================================================================
//
// 目标：让路由更像框架（支持 :id 路径参数、统一取参、统一 JSON 回复、
//       before/after 钩子、简单 CORS 钩子），仍保持零动态内存。
// 实现已内联到 lwip_http_api.c，无需新增文件。
// ------------------------------------------------------------------------

// 1) 路由语法糖：允许 handler 知道自己注册的 pattern（便于 :id 提取）
//    你的业务 handler 形如：int my_handler(const http_req_t*, http_res_t*, const char* pattern)
typedef int (*httpx_handler_t)(const http_req_t* r, http_res_t* s, const char* pattern);

// ——“声明/注册分离”宏：避免在函数体内产生嵌套函数（ISO C 禁止）——
// 在“文件作用域”使用下述 DEF 宏生成包装器；在 HTTP_API_user_routes 中用 ROUTE 宏注册。
#define HTTPX_DEF_GET(path, fn)                                             \
  static const char* fn##_httpx_pattern = (path);                           \
  static int fn##_httpx_wrap(const http_req_t* r, http_res_t* s) {          \
    return fn(r, s, fn##_httpx_pattern);                                    \
  }

#define HTTPX_DEF_POST(path, fn)                                            \
  static const char* fn##_httpx_pattern = (path);                           \
  static int fn##_httpx_wrap(const http_req_t* r, http_res_t* s) {          \
    return fn(r, s, fn##_httpx_pattern);                                    \
  }

#define HTTPX_ROUTE_GET(fn)   HTTP_API_register(HM_GET,  fn##_httpx_pattern, fn##_httpx_wrap)
#define HTTPX_ROUTE_POST(fn)  HTTP_API_register(HM_POST, fn##_httpx_pattern, fn##_httpx_wrap)

// 2) 统一取参（优先 JSON，其次 query/form），零依赖三方 JSON 库
int  httpx_get_int (const http_req_t* r, const char* key, int defv);           // 支持 true/false/数字
int  httpx_get_bool(const http_req_t* r, const char* key, int defv);           // "1/0/true/false/yes/no"
int  httpx_get_str (const http_req_t* r, const char* key, char* out, int cap); // 写入 out，返回字节数

// 3) 路径参数：pattern 支持 "/a/:id/b" 风格；name 传 "id"
int  httpx_path_param(const http_req_t* r, const char* pattern,
                      const char* name, char* out, int cap);

// 4) 统一 JSON 回复（自动设置 content-type）
//    成功：{"ok":true,...}\n
//    失败：{"ok":false,"code":<int>,"msg":"..."}\n
void httpx_res_json (http_res_t* s);                       // 设置 content-type = application/json
int  httpx_ok       (http_res_t* s);                       // 仅 {"ok":true}\n
int  httpx_okf      (http_res_t* s, const char* fmt, ...); // 附带自定义键值：httpx_okf(s, "\"sum\":%d", v);
int  httpx_err      (http_res_t* s, int code, const char* msg);
int  httpx_errf     (http_res_t* s, int code, const char* fmt, ...);

// 5) 可选全局钩子（返回非 0 表示拦截，不再进入业务 handler）
typedef int  (*httpx_before_cb)(const http_req_t* r, http_res_t* s);
typedef void (*httpx_after_cb )(const http_req_t* r, http_res_t* s, int handler_ret);

void httpx_set_before(httpx_before_cb cb);
void httpx_set_after (httpx_after_cb  cb);
int  httpx_run_before(const http_req_t* r, http_res_t* s);
void httpx_run_after (const http_req_t* r, http_res_t* s, int ret);

// 6) 简易 CORS 钩子（如果底层支持“添加自定义响应头”，可在实现里调用相应接口）
void httpx_apply_cors(http_res_t* s, const char* allow_origin);

#ifdef __cplusplus
}
#endif
